// API 测试工具类
import { describe, it, expect, beforeEach, afterEach } from 'vitest'

// Mock 数据生成器
export class MockDataGenerator {
  // 生成用户数据
  static generateUser(overrides = {}) {
    return {
      id: '1',
      username: 'testuser',
      email: 'test@example.com',
      name: '测试用户',
      role: 'student',
      is_active: true,
      created_at: '2024-01-01T00:00:00Z',
      ...overrides
    }
  }

  // 生成题库数据
  static generateQuestionBank(overrides = {}) {
    return {
      id: '1',
      title: '测试题库',
      description: '这是一个测试题库',
      question_count: 10,
      created_at: '2024-01-01T00:00:00Z',
      updated_at: '2024-01-01T00:00:00Z',
      creator: '1',
      is_active: true,
      ...overrides
    }
  }

  // 生成题目数据
  static generateQuestion(overrides = {}) {
    return {
      id: '1',
      title: '测试题目',
      content: '这是一个测试题目内容',
      question_type: 'single_choice',
      difficulty: 'medium',
      score: 10,
      options: [
        { id: '1', content: '选项A', is_correct: false },
        { id: '2', content: '选项B', is_correct: true },
        { id: '3', content: '选项C', is_correct: false },
        { id: '4', content: '选项D', is_correct: false }
      ],
      tags: ['基础', '测试'],
      bank: '1',
      created_at: '2024-01-01T00:00:00Z',
      ...overrides
    }
  }

  // 生成考试数据
  static generateExam(overrides = {}) {
    return {
      id: '1',
      title: '测试考试',
      description: '这是一个测试考试',
      exam_type: 'practice',
      duration: 60,
      total_score: 100,
      passing_score: 60,
      question_count: 10,
      status: 'published',
      start_time: '2024-01-01T10:00:00Z',
      end_time: '2024-01-01T12:00:00Z',
      created_by: '1',
      created_at: '2024-01-01T00:00:00Z',
      ...overrides
    }
  }

  // 生成成绩数据
  static generateGradeSheet(overrides = {}) {
    return {
      id: '1',
      exam: '1',
      student: '1',
      score: 85,
      total_score: 100,
      status: 'graded',
      start_time: '2024-01-01T10:00:00Z',
      end_time: '2024-01-01T11:30:00Z',
      created_at: '2024-01-01T00:00:00Z',
      ...overrides
    }
  }

  // 生成试卷模板数据
  static generatePaperTemplate(overrides = {}) {
    return {
      id: '1',
      title: '测试试卷模板',
      description: '这是一个测试试卷模板',
      paper_type: 'practice',
      generation_method: 'intelligent',
      total_score: 100,
      duration: 60,
      passing_score: 60,
      total_questions: 10,
      is_active: true,
      usage_count: 5,
      created_at: '2024-01-01T00:00:00Z',
      ...overrides
    }
  }
}

// API 响应格式化器
export class ApiResponseFormatter {
  static success(data: any, message = 'Success') {
    return {
      code: 200,
      message,
      data,
      success: true
    }
  }

  static error(message = 'Error', code = 400) {
    return {
      code,
      message,
      data: null,
      success: false
    }
  }

  static paginated(data: any[], total: number, page = 1, page_size = 20) {
    return this.success({
      results: data,
      count: total,
      next: page * page_size < total ? page + 1 : null,
      previous: page > 1 ? page - 1 : null
    })
  }
}

// HTTP 状态码常量
export const HTTP_STATUS = {
  OK: 200,
  CREATED: 201,
  NO_CONTENT: 204,
  BAD_REQUEST: 400,
  UNAUTHORIZED: 401,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  INTERNAL_SERVER_ERROR: 500
}

// 测试断言工具
export class TestAssertions {
  static assertValidApiResponse(response: any, expectData = true) {
    expect(response).toHaveProperty('success')
    expect(response).toHaveProperty('message')
    expect(response).toHaveProperty('code')
    if (expectData) {
      expect(response).toHaveProperty('data')
    }
  }

  static assertPaginatedResponse(response: any) {
    expect(response.data).toHaveProperty('results')
    expect(response.data).toHaveProperty('count')
    expect(response.data).toHaveProperty('next')
    expect(response.data).toHaveProperty('previous')
    expect(Array.isArray(response.data.results)).toBe(true)
  }

  static assertUser(user: any) {
    expect(user).toHaveProperty('id')
    expect(user).toHaveProperty('username')
    expect(user).toHaveProperty('email')
    expect(user).toHaveProperty('role')
  }

  static assertQuestion(question: any) {
    expect(question).toHaveProperty('id')
    expect(question).toHaveProperty('title')
    expect(question).toHaveProperty('content')
    expect(question).toHaveProperty('question_type')
    expect(question).toHaveProperty('difficulty')
    expect(question).toHaveProperty('score')
  }

  static assertExam(exam: any) {
    expect(exam).toHaveProperty('id')
    expect(exam).toHaveProperty('title')
    expect(exam).toHaveProperty('exam_type')
    expect(exam).toHaveProperty('duration')
    expect(exam).toHaveProperty('total_score')
    expect(exam).toHaveProperty('status')
  }

  static assertGradeSheet(gradeSheet: any) {
    expect(gradeSheet).toHaveProperty('id')
    expect(gradeSheet).toHaveProperty('exam')
    expect(gradeSheet).toHaveProperty('student')
    expect(gradeSheet).toHaveProperty('score')
    expect(gradeSheet).toHaveProperty('total_score')
    expect(gradeSheet).toHaveProperty('status')
  }
}

// API 测试基类
export class BaseApiTest {
  protected mockApi: any
  protected mockData: typeof MockDataGenerator
  protected assertions: typeof TestAssertions
  protected formatter: typeof ApiResponseFormatter

  constructor() {
    this.mockData = MockDataGenerator
    this.assertions = TestAssertions
    this.formatter = ApiResponseFormatter
  }

  beforeEach() {
    // 在每个测试前重置 mock
    vi.clearAllMocks()
  }

  afterEach() {
    // 在每个测试后清理
    vi.restoreAllMocks()
  }

  // Mock fetch 函数
  mockFetch(response: any, status = 200) {
    global.fetch = vi.fn().mockResolvedValue({
      ok: status >= 200 && status < 300,
      status,
      json: async () => response,
      text: async () => JSON.stringify(response)
    } as Response)
  }

  // Mock axios 响应
  mockAxiosResponse(response: any, status = 200) {
    vi.doMock('axios', () => ({
      default: {
        get: vi.fn().mockResolvedValue({ data: response, status }),
        post: vi.fn().mockResolvedValue({ data: response, status }),
        put: vi.fn().mockResolvedValue({ data: response, status }),
        delete: vi.fn().mockResolvedValue({ data: response, status }),
        patch: vi.fn().mockResolvedValue({ data: response, status })
      }
    }))
  }

  // Mock localStorage
  mockLocalStorage() {
    const store: Record<string, string> = {}
    global.localStorage = {
      getItem: vi.fn((key) => store[key] || null),
      setItem: vi.fn((key, value) => { store[key] = value }),
      removeItem: vi.fn((key) => { delete store[key] }),
      clear: vi.fn(() => { Object.keys(store).forEach(key => delete store[key]) }),
      get length() { return Object.keys(store).length },
      key: vi.fn((index) => Object.keys(store)[index] || null)
    } as any
  }
}

// 错误测试工具
export class ErrorTestUtils {
  static async expectApiError(apiCall: () => Promise<any>, expectedStatus = 400) {
    try {
      await apiCall()
      expect(true).toBe(false) // 如果没有抛出错误，测试失败
    } catch (error: any) {
      expect(error.response?.status).toBe(expectedStatus)
      this.assertions.assertValidApiResponse(error.response.data, false)
    }
  }

  static generateNetworkError() {
    return new Error('Network Error')
  }

  static generateTimeoutError() {
    return new Error('Request timeout')
  }
}